<?php
// +----------------------------------------------------------------------
// | BhAdmin [ BhAdmin匠心打造，我们相信，每个伟大的软件都有一个伟大的故事 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2020~2023 https://www.BhAdminshop.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed BhAdmin并不是自由软件，未经许可不能去掉BhAdmin相关版权
// +----------------------------------------------------------------------
// | Author: BAIHU  <admin@BhAdmin.com>
// +----------------------------------------------------------------------

namespace app\command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;

class InstallCommand extends Command
{
    protected static $defaultName = 'sp:install';
    protected static $defaultDescription = '初始化安装';

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int
     */
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        //安装将进行数据库迁移和菜单导入，是否继续?
        $helper = $this->getHelper('question');
        $question = new ConfirmationQuestion('<info>安装将进行数据库迁移和菜单导入，是否继续(请输入yes or no)?</info>', false, '/^(y)/i');
        if (!$helper->ask($input, $output, $question)) {
            $output->write('<error>已取消安装!</error>');
            return self::FAILURE;
        }
        $output->write("<info>开始执行检测扩展!</info>\n");
        $env = true;
        foreach (checkenv() as $key => $value) {
            if ($key == 'php' && (float)$value < 8) {
                $output->write("<error>您的php版本太低，不能安装本软件，兼容php版本8.x.x，谢谢！!</error>\n");
                $env = false;
                break;
            }
            if ($value == false && $value != 'redis') {
                $output->write("<error>" . $key . "扩展未安装！</error>\n");
                $env = false;
                break;
            }
        }
        if (!$env) {
            return self::FAILURE;
        }

        $output->write("<info>执行检测扩展结束!</info>\n");

        $output->write("<info>开始执行数据库安装!</info>\n");
        $res = $this->checkConnect();
        if ($res['code'] != 1) {
            $output->write("<error>" . $res['msg'] . "</error>\n");
            return self::FAILURE;
        }
        $installMysql = $this->installMysql();
        if ($res['code'] != 1) {
            $output->write("<error>" . $installMysql['msg'] . "</error>\n");
            return self::FAILURE;
        }
        $output->write("<info>数据库安装完成!</info>\n");
        $output->write("<info>后台初始账号：admin,密码：123456(温馨提示：请在后台立即修改密码)!</info>\n");
        $os = PHP_OS;
        $output->write("<info>请执行 php ".(strpos($os, 'LINUX')?'start.php':'windows.php')."  start 启动 </info>\n");
        return self::SUCCESS;
    }

    public function checkConnect()
    {
        $result = ['code' => 1, 'msg' => 'success'];
        if (!env('DB_HOST')) {
            return ['code' => 0, 'msg' => '请设置数据库地址'];
        }
        if (!env('DB_PORT')) {
            return ['code' => 0, 'msg' => '请设置数据库端口'];
        }
        if (!env('DB_NAME')) {
            return ['code' => 0, 'msg' => '请设置数据库名'];
        }
        if (!env('DB_USER')) {
            return ['code' => 0, 'msg' => '请设置数据库用户名'];
        }
        if (!env('DB_PASSWORD')) {
            return ['code' => 0, 'msg' => '请设置数据库密码'];
        }
        if (!env('REDIS_HOST')) {
            return ['code' => 0, 'msg' => '请设置Redis地址'];
        }
        if (!env('REDIS_PORT')) {
            return ['code' => 0, 'msg' => '请设置Redis端口'];
        }
        return $result;
    }

    public function installMysql()
    {
        $result = ['code' => 1, 'msg' => 'success'];
        // 链接数据库
        $connect = @mysqli_connect(env('DB_HOST') . ':' . env('DB_PORT'), env('DB_USER'), env('DB_PASSWORD'));
        if (!$connect) {
            return json(['code' => 0, 'msg' => '数据库链接失败！']);
        }
        // 检测MySQL版本
        $mysqlInfo = mysqli_get_server_info($connect);
        if ((float)$mysqlInfo < 5.7) {
            return json(['code' => 101, 'msg' => 'MySQL版本过低！']);
        }
        // 查询数据库名
        $database = mysqli_select_db($connect, env('DB_NAME'));
        if (!$database) {
            $query = "CREATE DATABASE IF NOT EXISTS `" . env('DB_NAME') . "` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;";
            if (!mysqli_query($connect, $query)) {
                return json(['code' => 101, 'msg' => '数据库创建失败或已存在，请手动修改！']);
            }
        } else {
            $mysql_table = mysqli_query($connect, 'SHOW TABLES FROM' . ' `' . env('DB_NAME') . '`');
            $mysql_table = mysqli_fetch_array($mysql_table);
            if (!empty($mysql_table) && is_array($mysql_table)) {
                return json(['code' => 101, 'msg' => '数据表已存在，请勿重复安装！']);
            }
        }
        $path = base_path() . '/data/bhadmin.sql';
        $sql = file_get_contents($path);
        $sql = str_replace("\r", "\n", $sql);
        $sql = explode(";\n", $sql);
        // 替换数据库表前缀
        $prefix = env('DB_PREFIX') ?? '';
        $sql = str_replace(" `{PREFIX}", " `{$prefix}", $sql);
        mysqli_select_db($connect, env('DB_NAME'));
        mysqli_query($connect, "set names utf8mb4");
        // 写入数据库
        foreach ($sql as $key => $value) {
            $value = trim($value);
            if (empty($value)) {
                continue;
            }
            if (substr($value, 0, 12) == 'CREATE TABLE') {
                $name = preg_replace("/^CREATE TABLE (\w+).*/s", "\1", $value);
                mysqli_query($connect, $value);
            } else {
                mysqli_query($connect, $value);
            }
        }
        return $result;
    }
}
